
import os
import tempfile
import shutil
import logging
logger = logging.getLogger('pkgr.tests.mockrepository')
TEST_COMPS = '''<comps>
<!--  <meta> -->
<!-- Meta information will go here eventually -->
<!--  </meta> -->
  <group>
    <id>testgroup</id>
    <name>Test Group</name>
    <default>true</default>
    <description>Test group</description>
    <uservisible>true</uservisible>
    <packagelist>
      <packagereq type="mandatory">a</packagereq>
      <packagereq type="mandatory">f</packagereq>
    </packagelist>
  </group>
</comps>
'''
class Group(object):
    def __init__(self, id, name, default=True, description="", uservisible=True, packagereqs=None):
        pass
    
class Package(object):
    def __init__(self, name, type=None):
        pass


# generic spec template
SPEC_TEMPLATE = '''
Name:           {name}
Version:        {version}
Release:        {release}
Summary:        package {name}
{extraheaders}
License:        BSD
BuildArch:      noarch
BuildRoot: %{{_tmppath}}/%{{name}}-%{{version}}-%{{release}}-root

%%description
package {name}

%%prep
%%build
%install
rm -rf $RPM_BUILD_ROOT
mkdir -p $RPM_BUILD_ROOT
touch  $RPM_BUILD_ROOT/{filename}

%files
/{filename}
'''

def gen_package_spec(name, extraheaders=""):
    return SPEC_TEMPLATE.format(name, extraheaders)




class MockSpec(object):
    def __init__(self, name, version, release, arch, extraheaders="", filename=None, template=SPEC_TEMPLATE):
        self.name = name
        self.version = version
        self.release = release
        self.arch = arch
        self.template = template
        self.extraheaders = extraheaders
        self.filename = filename if filename is not None else name
    
    def __str__(self):
        #print self.template
        return self.template.format(**self.__dict__)
 

SPECS = [
    # a
    # a -> b
    # a -> c
    MockSpec('a', 1, 1, 'noarch', 'Requires: b c'),
    MockSpec('b', 1, 1, 'noarch'),
    MockSpec('c', 1, 1, 'noarch'),
    # d conflicts a
    # d -> b
    MockSpec('d', 1, 1, 'noarch', "Requires: b\nConflicts: a"),
    # e (obsoleted)
    MockSpec('e', 1, 1, 'noarch'),
    # f (obsoletes e)
    MockSpec('f', 1, 1, 'noarch', 'Obsoletes: e', 'f1'),
    # an update to f
    MockSpec('f', 2, 1, 'noarch', 'Obsoletes: e', 'f2')
]

import subprocess
def rpmbuild(workingdir, spec, **kwargs):
    #cmd = 'rpmbuild -bb --define="_topdir {0}" --define="_sourcedir {0}" --define="_rpmdir {0}" --define="_builddir {0}" --define="_srcrpmdir {0}" --define="_speccdir {0}" {1}'.format(workingdir, spec)
   # print cmd
    #os.system(cmd)
    args = ['--define=_topdir {0}', '--define=_sourcedir {0}', '--define=_rpmdir {0}', '--define=_builddir {0}', '--define=_srcrpmdir {0}', '--define=_speccdir {0}', '{1}']
    args = [a.format(workingdir, spec) for a in args]
    args.append('--define=_rpmfilename %%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm')
    cmd = ["rpmbuild", "-bb"]+args
    #print ' '.join(cmd)
    process = subprocess.call(cmd, stdout=open(os.devnull, 'wb'), stderr=open(os.devnull, 'wb'))
    return os.path.join(workingdir, '{name}-{version}-{release}.{arch}.rpm'.format(**kwargs))
    # %define _rpmfilename %%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm

class MockRepository(object):
    def get_package(self, name):
        return self.packages.get(name)
        
    def open(self):
        self.packages = {}
        # create some fake packages:
        self.repodir = repodir = tempfile.mkdtemp()
        
        # create a fake repo somewhere on the filesystem
        self.rpmbuilddir = tempdir = tempfile.mkdtemp()
        
        for spec in SPECS:
            specpath = os.path.join(tempdir, '%s.spec' % spec.name)
            f = open(specpath, 'w')
            f.write(str(spec))
            f.close()
            rpmfile = rpmbuild(tempdir, specpath, name=spec.name, version=spec.version, release=spec.release, arch=spec.arch)
            #print rpmfile
            shutil.move(rpmfile, repodir)
            # copy to repodir
            self.packages[spec.name] = os.path.join(repodir, os.path.basename(rpmfile))
            logger.debug('Wrote: %s', os.path.basename(rpmfile))
            
        # copy over the fake comps
        compsfile = os.path.join(tempdir, 'comps.xml')
        f = open(compsfile, 'w')
        f.write(TEST_COMPS)
        f.close()
        
        # run a createrepo
        process = subprocess.call(['createrepo', '-g', compsfile, '--update', self.repodir], stdout=open(os.devnull, 'wb'), stderr=open(os.devnull, 'wb'))
        
        # now we have a fake local repo with a whole bunch of fake packages
        logger.debug('Created temporary repo at %s: %s', repodir, str(os.listdir(repodir)))
     
    def set_cachedir(self, d):
        pass
    
    def get_url(self):
        return "file://%s" % self.repodir
    
    #def init(self):
    #    repomdcache = self.join_cache_dir('repomd.xml')
    #    
    #    self.metadata = RepositoryMetadata()
    #    self.metadata.load_file(repomddata)
    #    
    #    
    #    self.database = RepositoryDatabase(self)
    #    self.database.load_primarydb(metadata['primary_db'])
    #    
    #    self.groups = Groups()
    #    self.groups.load_file(metadata['group'])
    
    def get_name(self):
        return "mockrepo"
        
    def close(self):
        shutil.rmtree(self.rpmbuilddir)
        #shutil.rmtree(self.repodir)
